<?php
	/* Functions in this file */
	/**************************/

	// DeleteScoreArrayContents()
	// DeserializeFormat1_7(&$stream)
	// GetBassScore()
	// GetChordNameFontSetting()
	// GetFadeIn()
	// GetFadeOut()
	// GetGuitarScore()
	// GetHeaderConstRef()
	// GetTablatureNumbersFontSetting()
	// GetTablatureStaffLineSpacing()
	// IsValidTablatureStaffLineSpacing($tablatureStaffLineSpacing)
	// Load($fileName)
	// LoadFile(&$stream)
	// LoadObject(&$stream)
	// PowerTabDocument()
	// SetFadeIn($fadeIn)
	// SetFadeOut($fadeOut)
	// SetTablatureNumbersFontSetting(&$fontSetting)
	// SetTablatureStaffLineSpacing($tablatureStaffLineSpacing)
?>
<?php
	 
	require_once "macros.php";
	require_once "systemsymbol.php";
	require_once "alternateending.php";
	require_once "barline.php";
	require_once "chorddiagram.php";
	require_once "chordname.php";
	require_once "chordtext.php";
	require_once "direction.php";
	require_once "dynamic.php";
	require_once "floatingtext.php";
	require_once "fontsetting.php";
	require_once "generalmidi.php";
	require_once "guitar.php";
	require_once "guitarin.php";
	require_once "keysignature.php";
	require_once "note.php";
	require_once "position.php";
	require_once "powertabfileheader.php";
	require_once "powertabinputstream.php";
	require_once "powertaboutputstream.php";
	require_once "powertabstream.php";
	require_once "rehearsalsign.php";
	require_once "rhythmslash.php";
	require_once "score.php";
	require_once "staff.php";
	require_once "system.php";
	require_once "tempomarker.php";
	require_once "timesignature.php";
	require_once "tuning.php";

	define('NUM_DOCUMENT_FONT_SETTINGS', 3);
	///< Number of document wide font settings
	define('DOCUMENT_FONT_SETTING_CHORD_NAME', 0);
	///< Font used to draw the chord name (chord text)
	define('DOCUMENT_FONT_SETTING_TABLATURE_NUMBERS', 1);
	///< Font used to draw the fret numbers on the tablature staff
	define('DOCUMENT_FONT_LYRICS', 2);
	///< Unused
	 
	 
	class PowerTabDocument {
		 
		 
		// Default Constants
		const DEFAULT_TABLATURE_STAFF_LINE_SPACING = 9;
		const DEFAULT_FADE_IN = 0;
		const DEFAULT_FADE_OUT = 0;
		 
		// Tablature Staff Line Spacing Constants
		const MIN_TABLATURE_STAFF_LINE_SPACING = 6;
		const MAX_TABLATURE_STAFF_LINE_SPACING = 14;
		 
		// Score Constants
		const NUM_SCORES = 2;
		const GUITAR_SCORE = 0;
		const BASS_SCORE = 1;
		 
		// Guitar Constants
		const MAX_GUITARS = 7;
		 
		 
		protected $m_header;
		protected $m_scoreArray;
		 
		protected $m_fontSettingArray = array ();
		protected $m_tablatureStaffLineSpacing;
		protected $m_fadeIn;
		protected $m_fadeOut = self::DEFAULT_FADE_OUT;
		 
		 
		/*
		function GetHeaderRef(){
		return ($this->m_header);
		}
		 
		*/
		function GetHeader() {
			return ($this->m_header);
		}
		 
		// Score Functions
		 
		 
		function GetGuitarScore() {
			if (!$this->m_scoreArray[0]) return NULL;
			 return ($this->m_scoreArray[0]);
		}
		 
		 
		function GetBassScore() {
			if (!sizeof($this->m_scoreArray) >= 2) return NULL;
			 return ($this->m_scoreArray[1]);
		}
		 
		// Font Setting Functions
		 
		 
		function SetChordNameFontSetting(&$fontSetting) {
			$this->m_fontSettingArray[DOCUMENT_FONT_SETTING_CHORD_NAME] = fontSetting;
		}
		 
		 
		function GetChordNameFontSetting() {
			return ($this->m_fontSettingArray[DOCUMENT_FONT_SETTING_CHORD_NAME]);
		}
		 
		 
		function & GetChordNameFontSettingRef() {
			return ($this->m_fontSettingArray[DOCUMENT_FONT_SETTING_CHORD_NAME]);
		}
		 
		 
		static function & GetChordNameFontSettingConstRef() {
			return ($this->m_fontSettingArray[DOCUMENT_FONT_SETTING_CHORD_NAME]);
		}
		 
		 
		 
		function SetTablatureNumbersFontSetting(&$fontSetting) {
			$this->m_fontSettingArray[DOCUMENT_FONT_SETTING_TABLATURE_NUMBERS] = $fontSetting;
		}
		 
		 
		function GetTablatureNumbersFontSetting() {
			return ($this->m_fontSettingArray[DOCUMENT_FONT_SETTING_TABLATURE_NUMBERS]);
		}
		 
		 
		function & GetTablatureNumbersFontSettingRef() {
			return ($this->m_fontSettingArray[DOCUMENT_FONT_SETTING_TABLATURE_NUMBERS]);
		}
		 
		 
		static function & GetTablatureNumbersFontSettingConstRef() {
			return ($this->m_fontSettingArray[DOCUMENT_FONT_SETTING_TABLATURE_NUMBERS]);
		}
		 
		// Tablature Staff Line Spacing Functions
		 
		 
		 
		function IsValidTablatureStaffLineSpacing($tablatureStaffLineSpacing) {
			return (($tablatureStaffLineSpacing >= self::MIN_TABLATURE_STAFF_LINE_SPACING) && ($tablatureStaffLineSpacing <= self::MAX_TABLATURE_STAFF_LINE_SPACING));
		}
		 
		 
		function SetTablatureStaffLineSpacing($tablatureStaffLineSpacing) {
			if (!$this->IsValidTablatureStaffLineSpacing($tablatureStaffLineSpacing)) return 0;
			$this->m_tablatureStaffLineSpacing = $tablatureStaffLineSpacing;
			 return 1;
		}
		 
		 
		function GetTablatureStaffLineSpacing() {
			return ($this->m_tablatureStaffLineSpacing);
		}
		 
		// Fade In Functions
		 
		 
		function SetFadeIn($fadeIn) {
			$this->m_fadeIn = $fadeIn;
		}
		 
		 
		function GetFadeIn() {
			return ($this->m_fadeIn);
		}
		 
		// Fade $this->Out Functions
		 
		 
		function SetFadeOut($fadeOut) {
			$this->m_fadeOut = $fadeOut;
		}
		 
		 
		function GetFadeOut() {
			return ($this->m_fadeOut);
		}
		 
		 
		// Constructor/Destructor
		 
		 
		function PowerTabDocument() {
			 
			 
			//$this->DeleteContents();
			$this->m_header = new PowerTabFileHeader ();
			$this->m_scoreArray[0] = new Score ();
			$this->m_scoreArray[1] = new Score ();
			
			$fontSettingIndex = 0;
			for (; $fontSettingIndex < NUM_DOCUMENT_FONT_SETTINGS; $fontSettingIndex++) {
				$this->m_fontSettingArray[$fontSettingIndex] = new FontSetting ();
			}
			
		}
		 
		// Save Functions
		 
		function SaveObject(&$stream){
		 
		
			// Write the header
			$this->m_header->Serialize($stream);
			

			// Write the scores
			$i = 0;
			$count = sizeof($this->m_scoreArray);
			for (; $i < $count; $i++) {
				$this->m_scoreArray[$i]->DoSerialize($stream);
			}

			// Write the document font settings
			$fontSettingIndex = 0;
			for (; $fontSettingIndex < NUM_DOCUMENT_FONT_SETTINGS; $fontSettingIndex++) {
				$this->m_fontSettingArray[$fontSettingIndex]->DoSerialize($stream);
			}

			// Write the line spacing and fade values
			WRITE_SIGNED_INTEGER ($stream,$this->m_tablatureStaffLineSpacing);
			WRITE_INTEGER ($stream,$this->m_fadeIn);
			WRITE_INTEGER ($stream,$this->m_fadeOut);

			//$stream->Debug();
			
			return 1;
		}
		
		// $this->Load Functions
		 
		 
		 
		function LoadObject(&$stream) {
			 
			 
			// Read the header
			$this->m_header->Deserialize($stream);
			 
			// Get the file $version
			$version = $this->m_header->GetVersion();
			 
			 
			DeserializeFormat1_7($stream);
			
			 
			return 1;
		}
		 
		function Save($fileName) {
			 
			
			$stream = new PowerTabOutputStream ($fileName);
			 
			 
			return ($this->SaveObject($stream));
		} 
		 
		function Load($fileName) {
			 
			/*
			if (!$fileName) return 0;
			 
			// Create a stream
			$stream = fopen($fileName, "rb");
			 
			if (!$stream)
				return 0;
			*/
			$stream = new PowerTabInputStream ($fileName);
			 
			// Create our special Power Tab stream, then call the sibling function
			//PowerTabInputStream $data_stream(stream);
			 
			return ($this->LoadFile($stream));
		}
	
		 
		function LoadFile(&$stream) {
			 
			
			//$this->DeleteContents();
			 
			// Read the header
			$this->m_header->Deserialize($stream);
			 
			 
			$version = $this->m_header->GetVersion();
			 
			$this->DeserializeFormat1_7($stream);
			 
			return 1;
		}
		 
		 
		 
		 
		function DeserializeFormat1_7(&$stream) {
			 
			
			 
			// Set the $version
			$version = PowerTabFileHeader::FILEVERSION_1_7;
			 
			// Read the guitar score
			$this->m_scoreArray[0] = new Score ();
			$this->m_scoreArray[0]->DoDeserialize($stream);
			 
			 
			// Read the bass score
			$this->m_scoreArray[1] = new Score ();
			$this->m_scoreArray[1]->DoDeserialize($stream);
			 
			// Read the document font settings
			$fontSettingIndex = 0;
			for (; $fontSettingIndex < NUM_DOCUMENT_FONT_SETTINGS; $fontSettingIndex++) {
				 
				$fontSetting = new FontSetting ();
				$fontSetting->DoDeserialize($stream);
				 
				 
				$this->m_fontSettingArray[$fontSettingIndex] = $fontSetting;
			}
			 
			// Read the line spacing and fade values
			$this->m_tablatureStaffLineSpacing = READ_SIGNED_INTEGER ($stream);
			$this->m_fadeIn = READ_INTEGER ($stream);
			$this->m_fadeOut = READ_INTEGER ($stream);
			 
			//$stream->Debug();
			 
			return 1;
		}
		 
		 
		 
		 
		// Score Functions
		 
		/*
		 
		function CanMergeGuitarScore($this->PowerTabDocument& document){
		 
		//------Last Checked------//
		// - Jan 9, 2005
		 
		// In order to merge, we must meet three requirements:
		// 1) Line spacing on the tablature staff must be the same
		// 2) All document font settings must be the same
		// 3) We must not have more than seven guitars total after the merge
		 
		// 1)
		if ($this->m_tablatureStaffLineSpacing != document.$this->m_tablatureStaffLineSpacing)
		return 0;
		 
		// 2)
		$fontSettingIndex = 0;
		for (; $fontSettingIndex < NUM_DOCUMENT_FONT_SETTINGS; $fontSettingIndex++) {
		 
		if ($this->m_fontSettingArray[$fontSettingIndex] != document.$this->m_fontSettingArray[$fontSettingIndex])
		return 0;
		}
		 
		// 3)
		Score* guitarScore = $this->GetGuitarScore();
		if (!guitarScore != NULL) return 0;
		Score* bassScore = document.$this->GetBassScore();
		if (!bassScore != NULL) return 0;
		 
		if ((guitarScore->GetGuitarCount() + bassScore->GetGuitarCount()) > self::MAX_GUITARS)
		return 0;
		 
		return 1;
		}
		 
		 
		 
		 
		function MergeGuitarScore($this->PowerTabDocument& document){
		 
		//------Last Checked------//
		// - Jan 26, 2005
		 
		// If we can't merge, bail out
		if (!$this->CanMergeGuitarScore(document))
		return 0;
		 
		// Get a pointer to the score we're merging
		Score* fromGuitarScore = document.$this->GetGuitarScore();
		if (!fromGuitarScore != NULL) return 0;
		 
		// Get the current guitar score
		Score* oldGuitarScore = $this->GetGuitarScore();
		if (!oldGuitarScore != NULL) return 0;
		 
		// Make a copy of the score
		Score* mergeGuitarScore = (Score*)fromGuitarScore->CloneObject();
		if (!mergeGuitarScore != NULL) return 0;
		 
		// Update the guitar score
		$this->m_scoreArray[0] = mergeGuitarScore;
		 
		// Delete the old guitar score
		delete oldGuitarScore;
		 
		return 1;
		}
		 
		 
		 
		 
		function CanMergeBassScore($this->PowerTabDocument& document){
		 
		//------Last Checked------//
		// - Jan 9, 2005
		 
		// In order to merge, we must meet three requirements:
		// 1) Line spacing on the tablature staff must be the same
		// 2) All document font settings must be the same
		// 3) We must not have more than seven guitars total after the merge
		 
		// 1)
		if ($this->m_tablatureStaffLineSpacing != document.$this->m_tablatureStaffLineSpacing)
		return 0;
		 
		// 2)
		$i = 0;
		for (; i < NUM_DOCUMENT_FONT_SETTINGS; i++) {
		 
		if ($this->m_fontSettingArray[i] != document.$this->m_fontSettingArray[i])
		return 0;
		}
		 
		// 3)
		Score* guitarScore = $this->GetGuitarScore();
		if (!guitarScore != NULL) return 0;
		Score* bassScore = document.$this->GetBassScore();
		if (!bassScore != NULL) return 0;
		 
		if ((guitarScore->GetGuitarCount() + bassScore->GetGuitarCount()) > self::MAX_GUITARS)
		return 0;
		 
		return 1;
		}
		 
		 
		 
		 
		function MergeBassScore($this->PowerTabDocument& document){
		 
		//------Last Checked------//
		// - Jan 26, 2005
		 
		// If we can't merge, bail out
		if (!$this->CanMergeBassScore(document))
		return 0;
		 
		// Get a pointer to the score we're merging
		Score* fromBassScore = document.$this->GetBassScore();
		if (!fromBassScore != NULL) return 0;
		 
		// Get the current bass score
		Score* oldBassScore = $this->GetBassScore();
		if (!oldBassScore != NULL) return 0;
		 
		// Make a copy of the score
		Score* mergeBassScore = (Score*)fromBassScore->CloneObject();
		if (!mergeBassScore != NULL) return 0;
		 
		// Update the bass score
		$this->m_scoreArray[1] = mergeBassScore;
		 
		// Delete the old bass score
		delete oldBassScore;
		 
		return 1;
		}
		*/
		 
		function DeleteScoreArrayContents() {
			 
			 
			$this->m_scoreArray = array ();
		}
		 
		 
		 
	}
	 
?>

